﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Xrm.Sdk;
using CrmCodeGenerator.Core;

namespace CrmCodeGenerator.UI
{
    public partial class Options : Form
    {
        public Options()
        {
            InitializeComponent();
        }

        #region multi-threading stuff
        private void ToggleControl(Control c, bool enabled)
        {
            if (c.InvokeRequired)
            {
                c.BeginInvoke(new MethodInvoker(delegate()
                {
                    c.Enabled = enabled;
                }));
            }
            else { c.Enabled = enabled; }
        }

        private void UpdateStatus(string msg)
        {
            if (this.statusStrip1.InvokeRequired)
            {
                this.statusStrip1.BeginInvoke(new MethodInvoker(delegate()
                {
                    this.statusmsg.Text = msg;
                }));
            }
            else { this.statusmsg.Text = msg; }
        }
        #endregion

        public IOrganizationService Connection { get; set; }

        private delegate void GenerateCodeHandler(Mapper mapper);

        private void t4browse_Click(object sender, EventArgs e)
        {
            var ofd = new OpenFileDialog { Filter = "T4 (*.tt)|*.tt" };
            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                this.t4path.Text = ofd.FileName;
            }
        }

        private void outputbrowse_Click(object sender, EventArgs e)
        {
            var ofd = new OpenFileDialog { };
            if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                this.outputpath.Text = ofd.FileName;
            }
        }

        private void generate_Click(object sender, EventArgs e)
        {
            ToggleControl(this.generate, false);

            Mapper mapper = new Mapper
            {
                Settings = new Core.Model.Settings
                {
                    CrmConnection = this.Connection,

                    T4Path = this.t4path.Text,
                    OutputPath = this.outputpath.Text,

                    EntitiesToInclude = (this.includeentities.Text ?? "").Split(','),
                    EntitiesToExclude = (this.excludeentities.Text ?? "").Split(','),

                    Context = new Core.Model.Context
                    {
                        Namespace = this.nspace.Text,
                    }
                }
            };

            mapper.Message += new MapperHandler(mapper_Message);

            GenerateCodeHandler gch = new GenerateCodeHandler(BeginCodeGeneration);
            gch.BeginInvoke(mapper, new AsyncCallback(EndCodeGeneration), gch);
        }

        private void BeginCodeGeneration(Mapper mapper)
        {
            mapper.MapEntities();
        }

        private void EndCodeGeneration(IAsyncResult result)
        {
            GenerateCodeHandler gch = result.AsyncState as GenerateCodeHandler;
            gch.EndInvoke(result);

            ToggleControl(this.generate, true);
        }

        private void mapper_Message(object sender, MapperEventArgs e)
        {
            UpdateStatus(e.Message);
        }
    }
}
